From 2e93467bf20423c7449f2bb25dadd5894c4525b3 Mon Sep 17 00:00:00 2001 From: "kaf24@labyrinth.cl.cam.ac.uk" Date: Wed, 25 Aug 2004 15:38:29 +0000 Subject: [PATCH] bitkeeper revision 1.1159.51.1 (412cb2756vYHD-1PDPrd90VZuLl1EQ) Fix netif and blkif interface deferred disconnection. It must occur in a process context because we call vfree(). --- linux-2.4.27-xen-sparse/include/asm-xen/queues.h | 5 ++++- linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h | 6 ++++-- .../drivers/xen/blkback/interface.c | 11 +++++++++-- linux-2.6.7-xen-sparse/drivers/xen/netback/common.h | 6 ++++-- .../drivers/xen/netback/interface.c | 11 +++++++++-- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/linux-2.4.27-xen-sparse/include/asm-xen/queues.h b/linux-2.4.27-xen-sparse/include/asm-xen/queues.h index 95bddf3887..dd527603ce 100644 --- a/linux-2.4.27-xen-sparse/include/asm-xen/queues.h +++ b/linux-2.4.27-xen-sparse/include/asm-xen/queues.h @@ -10,8 +10,11 @@ #define DECLARE_TQUEUE(_name, _fn, _arg) \ struct tq_struct _name = { LIST_HEAD_INIT((_name).list), 0, _fn, _arg } - #define DECLARE_WORK(_name, _fn, _arg) DECLARE_TQUEUE(_name, _fn, _arg) + +#define work_struct tq_struct +#define INIT_WORK(_work, _fn, _arg) INIT_TQUEUE(_work, _fn, _arg) + #define schedule_work(_w) schedule_task(_w) #endif /* __QUEUES_H__ */ diff --git a/linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h b/linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h index 0d1fbc2e4e..0fa60cdceb 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h @@ -60,19 +60,21 @@ typedef struct blkif_st { struct list_head blkdev_list; spinlock_t blk_ring_lock; atomic_t refcnt; + + struct work_struct work; } blkif_t; void blkif_create(blkif_be_create_t *create); void blkif_destroy(blkif_be_destroy_t *destroy); void blkif_connect(blkif_be_connect_t *connect); int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id); -void __blkif_disconnect_complete(blkif_t *blkif); +void blkif_disconnect_complete(blkif_t *blkif); blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle); #define blkif_get(_b) (atomic_inc(&(_b)->refcnt)) #define blkif_put(_b) \ do { \ if ( atomic_dec_and_test(&(_b)->refcnt) ) \ - __blkif_disconnect_complete(_b); \ + blkif_disconnect_complete(_b); \ } while (0) /* An entry in a list of xen_extents. */ diff --git a/linux-2.6.7-xen-sparse/drivers/xen/blkback/interface.c b/linux-2.6.7-xen-sparse/drivers/xen/blkback/interface.c index 3cd76b7120..4196014597 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkback/interface.c +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkback/interface.c @@ -27,13 +27,14 @@ blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle) return blkif; } -void __blkif_disconnect_complete(blkif_t *blkif) +static void __blkif_disconnect_complete(void *arg) { + blkif_t *blkif = (blkif_t *)arg; ctrl_msg_t cmsg; blkif_be_disconnect_t disc; /* - * These can't be done in __blkif_disconnect() because at that point there + * These can't be done in blkif_disconnect() because at that point there * may be outstanding requests at the disc whose asynchronous responses * must still be notified to the remote driver. */ @@ -67,6 +68,12 @@ void __blkif_disconnect_complete(blkif_t *blkif) ctrl_if_send_response(&cmsg); } +void blkif_disconnect_complete(blkif_t *blkif) +{ + INIT_WORK(&blkif->work, __blkif_disconnect_complete, (void *)blkif); + schedule_work(&blkif->work); +} + void blkif_create(blkif_be_create_t *create) { domid_t domid = create->domid; diff --git a/linux-2.6.7-xen-sparse/drivers/xen/netback/common.h b/linux-2.6.7-xen-sparse/drivers/xen/netback/common.h index 6910c61165..6646f5339f 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/netback/common.h +++ b/linux-2.6.7-xen-sparse/drivers/xen/netback/common.h @@ -70,19 +70,21 @@ typedef struct netif_st { spinlock_t rx_lock, tx_lock; struct net_device *dev; struct net_device_stats stats; + + struct work_struct work; } netif_t; void netif_create(netif_be_create_t *create); void netif_destroy(netif_be_destroy_t *destroy); void netif_connect(netif_be_connect_t *connect); int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id); -void __netif_disconnect_complete(netif_t *netif); +void netif_disconnect_complete(netif_t *netif); netif_t *netif_find_by_handle(domid_t domid, unsigned int handle); #define netif_get(_b) (atomic_inc(&(_b)->refcnt)) #define netif_put(_b) \ do { \ if ( atomic_dec_and_test(&(_b)->refcnt) ) \ - __netif_disconnect_complete(_b); \ + netif_disconnect_complete(_b); \ } while (0) void netif_interface_init(void); diff --git a/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c index 76d23171b2..406d253fda 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c @@ -27,13 +27,14 @@ netif_t *netif_find_by_handle(domid_t domid, unsigned int handle) return netif; } -void __netif_disconnect_complete(netif_t *netif) +static void __netif_disconnect_complete(void *arg) { + netif_t *netif = (netif_t *)arg; ctrl_msg_t cmsg; netif_be_disconnect_t disc; /* - * These can't be done in __netif_disconnect() because at that point there + * These can't be done in netif_disconnect() because at that point there * may be outstanding requests at the disc whose asynchronous responses * must still be notified to the remote driver. */ @@ -70,6 +71,12 @@ void __netif_disconnect_complete(netif_t *netif) ctrl_if_send_response(&cmsg); } +void netif_disconnect_complete(netif_t *netif) +{ + INIT_WORK(&netif->work, __netif_disconnect_complete, (void *)netif); + schedule_work(&netif->work); +} + void netif_create(netif_be_create_t *create) { int err = 0; -- 2.30.2